package com.share.config.log.spel;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Slf4j
@Aspect
@Component
public class AopLogSpel {

    //解析spel表达式
    ExpressionParser parser = new SpelExpressionParser();

    //将方法参数纳入Spring管理
    LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();

    @Pointcut("@annotation(com.share.config.log.spel.LogSpel)")
    public void logPointCut() {
    }

    @Around("logPointCut()")
    public Object invoked(ProceedingJoinPoint pjp) throws Throwable {
        //获取参数对象数组
        Object[] args = pjp.getArgs();
        //获取方法
        Method method = ((MethodSignature) pjp.getSignature()).getMethod();
        LogSpel log = method.getAnnotation(LogSpel.class);
        String spel = log.content();
        //获取方法参数名
        String[] params = discoverer.getParameterNames(method);
        //将参数纳入Spring管理
        EvaluationContext context = new StandardEvaluationContext();
        for (int len = 0; len < params.length; len++) {
            context.setVariable(params[len], args[len]);
        }
        Expression expression = parser.parseExpression(spel);
        spel = expression.getValue(context, String.class);
        System.err.println("---------->>>>审计日志内容为：" + spel);
        return pjp.proceed();
    }
}
